package com.tc.itfarm.commons.mybatis.plugins;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.Iterator;
import java.util.List;

/**
 * 
 * @Description: sql 自动生成分页插件   
 * @author: wangdongdong  
 * @date:   2016年7月4日 下午3:00:04   
 *
 */
public class SqlPaginationPlugin extends PluginAdapter {

	
	
	public SqlPaginationPlugin() {
		super();
	}

	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}

	@Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        // add field, getter, setter for limit clause
        boolean success = super.modelExampleClassGenerated(topLevelClass, introspectedTable);
        addPage(topLevelClass);
        return success;
    }

    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        XmlElement parentElement = document.getRootElement();

        // 产生分页语句
        XmlElement paginationElement = new XmlElement("sql");
        paginationElement.addAttribute(new Attribute("id", "SqlDialectPage"));

        XmlElement offsetXml = new XmlElement("if");
        offsetXml.addAttribute(new Attribute("test", "page != null and page.begin != null and page.begin gte 0"));
        offsetXml.addElement(new TextElement("limit #{page.begin}"));
        paginationElement.addElement(offsetXml);

        XmlElement limitXml = new XmlElement("if");
        limitXml.addAttribute(new Attribute("test", "page != null and page.pageSize != null and page.pageSize gte 0"));
        limitXml.addElement(new TextElement(", #{page.pageSize}"));
        paginationElement.addElement(limitXml);

        parentElement.addElement(paginationElement);

        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    @Override
    public boolean sqlMapSelectByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {

        XmlElement pageXml = new XmlElement("include"); //$NON-NLS-1$
        pageXml.addAttribute(new Attribute("refid", "SqlDialectPage"));
        int len = element.getElements().size();
        element.getElements().add(len, pageXml);

        return super.sqlMapUpdateByExampleWithoutBLOBsElementGenerated(element, introspectedTable);
    }

    /**
     * @param topLevelClass
     */
    private void addPage(TopLevelClass topLevelClass) {

        String fullTypeSpecification = properties.getProperty("pageCriteriaPackage") + ".PageCriteria";
        topLevelClass.addImportedType(new FullyQualifiedJavaType(fullTypeSpecification));
        topLevelClass.setSuperClass(new FullyQualifiedJavaType(fullTypeSpecification));
        Iterator<Field> fieldIterator = topLevelClass.getFields().iterator();
        while (fieldIterator.hasNext()) {
            Field field = fieldIterator.next();
            if (field.getName().equals("orderByClause")) {
                fieldIterator.remove();
            }
        }
        Iterator<Method> methodIterator = topLevelClass.getMethods().iterator();
        while (methodIterator.hasNext()) {
            Method method = methodIterator.next();
            if (method.getName().equals("setOrderByClause") || method.getName().equals("getOrderByClause")) {
                methodIterator.remove();
            }
        }

        Iterator<InnerClass> classIteratorIterator = topLevelClass.getInnerClasses().iterator();
        while (classIteratorIterator.hasNext()) {
            InnerClass innerClass = classIteratorIterator.next();
            if (innerClass.getType().getShortName().equals("Criterion")) {
                classIteratorIterator.remove();
            }
        }
    }
}
